<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
    //（1）this的使用
    var hero = {
        name: 'sky',
        sayName: function() {
            return this.name;//this指向当前对象
        }
    };
    >hero.name;//"sky"
    //(2)通过构造器函数来创建对象{一般会将构造器函数的首字母大写}
    function Hero() {
        this.occupation = 'Ninja';
    };
    var hero = new Hero();
    console.log(typeof Hero);//"function"
    console.log(hero.occupation);//"Ninja"
    //(2-1)构造器函数传参问题
    function Hero(name) {
        this.name = name;
        this.occupation = 'Ninja';
        this.whoAreYou = function() {
            return "I'm" +
                    this.name +
                    " and I'm a " +
                    this.occupation;
        };
    };
    //现在我们就能利用同一个构造器来创建不同的对象了
    var h1 = new Hero('SKY');
    var h2 = new Hero('MOON');
    >h1.whoAreYou();//"I‘m SKY and I'm a Ninja;
    //(2-2)不使用new去调用构造器函数会发生什么事情
    >var h = Hero('FUCK');
    >typeof h;//"undefined"
    /*假如不使用new，那么这和普通的函数调用是没有什么区别的，而由于该函数没有显示
    返回值，所以实际上返回的是undefined;并将该值赋给了h
    那么这种情况下，this指向的是是哪里？答案是全局对象
     */
    //(3)全局对象和全局变量问题
    var a = 1;
    >window.a;//1
    >this.a;//1构造函数之外使用this，this指向的是宿主环境widow

    //继续讨论（2-2）中的不使用new的实例化对象
    >function Hero(name) {
        this.name = name;
    }
    >var h = Hero('sky');
    >typeof h;//"undefined";
    typeof h.name;//TypeError:Cannot read property 'name’ of undefined
    //但是，由于在Hero中使用了this，所以这里就会创建一个全局变量（而全局变量又是全局对象的一个属性）
    >name;//'sky'
    >window.name;//'sky'
    >var h2 = new Hero('moon');
    >typeof  h2;//"object"
    >h2.name;//'moon';
    //(3-1)系统预置的那些函数就是window对象的方法
    >parseInt('123sky');//123
    >window.parseInt('123sky');//123
    >this.parseInt('123sky');//123这个this要保证是在所有函数之外使用
    //(4)构造器属性
    >h2.constructor;
    //constructor构造器属性指向用于创建该对象的构造器函数的引用【即h2.constructor就是构造函数Hero】
    function Hero(name) {
        this.name = name;
    }
    //由于构造器属性所引用的是一个函数，因此我们也可利用它来创建一个其他新对象
    >var h3 = new h2.contstructor('fun');
    >h3.name;//'fun'
    /*(4-1)如果对象是通过对象文本标识发创建，那么实际上它是由内建构造器Object（）函数
    所创建的
     */
    >var o = {};
    >o.constructor;//function Object() {native code}
    >typeof o.constructor;//'function'
    //(5)instanceo操作符，通过该操作符，我们可以测试一个对象是不是由某个制定的构造器函数所创建的
    >function Hero() {}
    >var h = new Hero();
    >var o = {};
    >h instanceof Hero;//true

    >h instanceof Object;//true
    >o instanceof Object;//true
    //(6)返回对象的函数
    //(6-1)使用一般函数来创建对象
    function factory(name) {
        return {
            name: name
        };
    };
    var o = factory('one');
    console.log(o.name);//'one'
    o.constructor;//function Objec() { [native code] }
    //(6-2)构造器函数也可以返回对象
    function C() {
        //实际上这里有个这样的逻辑：var this = {}。前提是我们使用了new来实例化。
        this.a = 1;
        //最终结尾又有这样的逻辑：return this
    };
    var c = new C();
    console.log(c.a);//1
    //现在考虑这种用法
    function C2(){
        this.a = 1;
        return {b:2};
    }
    var c2 = new C2();
    typeof  c2.a;//'undefined'/这是因为返回的对象已经是return那个对象
    c2.b;//2

</script>
</body>
</html>